
#include <windows.h>

extern "C"{
#include "EbTftpSimuClnt.h"
#include "args.h"

BOOL EbSimuEthInit(BYTE *pbBaseAddress, DWORD dwMultiplier, USHORT MacAddr[3]);
UINT16 EbSimuEthGetFrame(PUCHAR pData, PUSHORT pwLength);
UINT16 EbSimuEthSendFrame(PUCHAR pData, DWORD dwLength);
}

CEbootSimuBin g_EbSimuBin;
CEbootMemBin g_EbMemBin;
CEbTftpSimuClnt g_EbTftpSimuClnt;
CEbSimuTransEther g_EbSimuEther;


BYTE g_bufEbTftp[TFTP_PKT_LEN];
BOOL g_fTftpProcess=FALSE;

BOOL EbSimuEthInit(BYTE *pbBaseAddress, DWORD dwMultiplier, USHORT MacAddr[3])
{
	PBOOT_CFG pBootCfg=PBOOT_CFG(pbBaseAddress);
	EDBG_ADDR ebTftpAddr, simuAddr;

	g_fTftpProcess=FALSE;

#if 0
	g_EbSimuBin.Init(0x80200000, 16*1024*1024, 256);
	g_EbTftpSimuClnt.Init(&g_EbSimuBin, "boot.bin");
#else
	g_EbMemBin.Init(0x82000000, 16*1024*1024);
	g_EbTftpSimuClnt.Init(&g_EbMemBin, "boot.bin");
#endif	

	memcpy(&ebTftpAddr.wMAC, pBootCfg->CS8900MAC, sizeof(ebTftpAddr.wMAC));
	ebTftpAddr.dwIP=pBootCfg->IPAddr;
	ebTftpAddr.wPort=ntohs(EDBG_DOWNLOAD_PORT);

	simuAddr.wMAC[0]=ebTftpAddr.wMAC[1];
	simuAddr.wMAC[1]=ebTftpAddr.wMAC[2];
	simuAddr.wMAC[2]=ebTftpAddr.wMAC[0];
	simuAddr.dwIP=pBootCfg->IPAddr+(1<<24);
	simuAddr.wPort=ntohs(EDBG_DOWNLOAD_PORT);

	g_EbSimuEther.Init(&simuAddr, &ebTftpAddr);

	return TRUE;
}

UINT16 EbSimuEthGetFrame(PUCHAR pData, PUSHORT pwLength)
{
	WORD wLen;

	if(!g_fTftpProcess)
	{
//		EdbgOutputDebugString("EbSimuEthGetFrame no process!\r\n");
		return 0;
	}

	wLen=sizeof(g_bufEbTftp);
	if(g_EbTftpSimuClnt.EbootGetData( g_bufEbTftp, &wLen))
	{
		if(g_EbSimuEther.FormEthFrame(g_bufEbTftp, wLen, pData, pwLength))
		{
			return TRUE;
		}
	}

	EdbgOutputDebugString("EbSimuEthGetFrame faild\r\n");
	return FALSE;
}

// 0 ok , 1 err
UINT16 EbSimuEthSendFrame(PUCHAR pData, DWORD dwLength)
{
	BYTE* pDatabuf;
	DWORD dwDataLen;
	WORD wFramType=ntohs(*(WORD*)(pData+12));

	// not ip frame omit it IP_FRAME
	if(0x0800==wFramType)
	{
		WORD* pw=(WORD*)pData;
		// broad cast maybe bootme
		if( (0xffff==pw[0])
			&& (0xffff==pw[1])
			&& (0xffff==pw[2]) )
		{
			g_fTftpProcess=TRUE;
			return 0;
		}
		else
		{
			if(g_EbSimuEther.GetEtherPayload(pData, dwLength, &pDatabuf, &dwDataLen))
			{
				if(g_EbTftpSimuClnt.EbootSendData(pDatabuf, dwDataLen))
				{
					return 0;
				}
			}
		}
	}
	// 0x0806 arp ignore
	else if(0x0806==wFramType)
	{
		return 0;
	}
	
	EdbgOutputDebugString("EbSimuEthSendFrame unknown type:0x%x\r\n",  wFramType);
	return 1;
}


